#include "MT9818.h"
#include "delay.h"
#include "24Cxx.h"
#include "stdio.h"
#include "drv_pin.h"
#include "drv_soft_iic.h"
#include <string.h>
#include <stdlib.h>
#include "main.h"
#include "delay.h"
#include "systemdata.h"
#include "drv_timer.h"

///*****************************
//*****************************************************************
//* Local variables
//**********************************************************************************************/
//#define I2C_SCL_L		    GPIO_WriteBit(GPIO0, GPIO_Pin_5, Bit_RESET);
//#define I2C_SCL_H		    GPIO_WriteBit(GPIO0, GPIO_Pin_5, Bit_SET);
//#define I2C_SDA_L		    GPIO_WriteBit(GPIO0, GPIO_Pin_4, Bit_RESET);
//#define I2C_SDA_H		    GPIO_WriteBit(GPIO0, GPIO_Pin_4, Bit_SET);


OV_DELAY ov_delay_time = OV_DELAY_TWO_SECOND;
UV_DELAY uv_delay_time = UV_DELAY_FOUR_SECOND;
OCD_THRESH ocd_thresh = OCD_THRESH_95MV;
OCD_DELAY ocd_delay_time = OCD_DELAY_1280MS;
SCD_THRESH scd_thresh = SCD_THRESH_190MV;

SCD_DELAY scd_delay_time = SCD_DELAY_400US;

uint8_t i2c_rev_data[72] = {0};

void I2C_WriteBreq_MsgSBS(unsigned char SlaveAdd,unsigned char RegAdd,unsigned char date);
unsigned char I2C_GetRead_MsgSBS(unsigned char SlaveAdd,unsigned char RegAdd) ;
float Get_BAT_ADC_GAIN3(void);
uint8_t I2C_SDA_READ(void);
/**********************************************************************************************
* Local functions
**********************************************************************************************/
/***********************************************************************************************
*
* @brief    MT9818_Init
* @param    none
* @return   none
*
************************************************************************************************/  

void MT9818_I2C_Init(void){
	

}

void MT9818_Parameter_Init(void){
	uint8_t delay = 0;
	uint8_t ov_val = 0;
	uint8_t uv_val = 0;
	uint8_t sys_ctl = 0;
	double BAT_ADC_GAIN3;
	uint16_t temp = 0;
	volatile uint8_t protect_reg2 = 0,protect_reg1 = 0;
	#if 1
	//设置过压 欠压保护阈值及时间
	if (ov_delay_time == OV_DELAY_TWO_SECOND){		
			delay |= (1 << 4);
	}else if (ov_delay_time == OV_DELAY_FOUR_SECOND){
			delay |= (1 << 5);
	}else if (ov_delay_time == OV_DELAY_EIGHT_SECOND){
			delay = delay | (1 << 5) | (1 << 4);
	} 
	if (uv_delay_time == UV_DELAY_FOUR_SECOND)
	{		
			delay |= (1 << 6);
	}else if (uv_delay_time == UV_DELAY_EIGHT_SECOND){
			delay |= (1 << 7);
	}else if (uv_delay_time == UV_DELAY_SIXTEEN_SECOND){
			delay = delay | (1 << 6) | (1 << 7);
	} 	
	I2C_WriteBreq_MsgSBS(SLAVE_ADDRESS,PROTECT3_REG,delay);
	
	BAT_ADC_GAIN3 = Get_BAT_ADC_GAIN3(); 
 	ov_val = (uint8_t)( (uint16_t)(OVP_VALUE*1000/BAT_ADC_GAIN3)>>4 );
	I2C_WriteBreq_MsgSBS(SLAVE_ADDRESS,OV_TRIP_REG,ov_val);
//	uv_val = (uint8_t)( (uint16_t)(UVP_VALUE*1000/BAT_ADC_GAIN3)>>4 );
	temp =  (uint16_t)(UVP_VALUE*1000/BAT_ADC_GAIN3);
	if (temp < 0x1000)
		uv_val = 0x00;
	else 
		uv_val = (uint8_t)( temp >> 4 );
	I2C_WriteBreq_MsgSBS(SLAVE_ADDRESS,UV_TRIP_REG,uv_val);
	
//设置过流保护时间 阈值
	protect_reg1 = (scd_delay_time << 3) | (RSNS << 7) | scd_thresh;
	I2C_WriteBreq_MsgSBS(SLAVE_ADDRESS,PROTECT1_REG,protect_reg1);
	protect_reg2 = (ocd_delay_time << 4) | ocd_thresh;
	I2C_WriteBreq_MsgSBS(SLAVE_ADDRESS,PROTECT2_REG,protect_reg2);
//清除寄存器SYS_STAT
	I2C_WriteBreq_MsgSBS(SLAVE_ADDRESS,SYS_STAT_REG,0x9F);
//启动电流检测
//	sys_ctl = I2C_GetRead_MsgSBS(SLAVE_ADDRESS,SYS_CTRL2_REG);
//	sys_ctl |= (1<<6); 
	I2C_WriteBreq_MsgSBS(SLAVE_ADDRESS,SYS_CTRL2_REG,0X43);
#endif
}
void Set_SDA_Input(void)
{
    
}
void Set_SDA_Output(void){
    
}


//产生IIC起始信号
void IIC_Start(void){
//	Set_SDA_Output();
//	I2C_SDA_H;	
//	I2C_SCL_H;
//	delay_us(6);
//	I2C_SDA_L;
//	delay_us(8);
//	I2C_SCL_L;
//	delay_us(6);
}	 

//产生IIC停止信号
void IIC_Stop(void){
//	Set_SDA_Output();
//	I2C_SDA_L;
//	I2C_SCL_L;;
//	delay_us(5);
//	I2C_SCL_H;
//	delay_us(6);
//	I2C_SDA_H;
//	delay_us(15);
}

//读取SDA状态
uint8_t READ_I2CSDA(void) {
	uint8_t i;
//	i=GPIO_ReadDataBit(GPIO0, GPIO_Pin_4);
	return i;
}


//等待应答信号到来
void IIC_Wait_Ack(void){
//	uint8_t data = 0;
//	uint8_t time = 0;
//	
//	Set_SDA_Input();
//	I2C_SDA_H;
//	delay_us(20);
//	I2C_SCL_H;
//	data = READ_I2CSDA();
//	while(data)
//	{
//		time++;
//		if (time >= 250)
//		{
//			IIC_Stop();
////			MT9818_Init();
//			return;
//		}
//		data = READ_I2CSDA();
//	}
//	delay_us(10);
//	I2C_SCL_L;
//	delay_us(10);
} 


//产生ACK应答
void IIC_Ack(void){
//	I2C_SCL_L;
//	Set_SDA_Output();
//	delay_us(20);
//	I2C_SDA_L;
//	delay_us(2);
//	I2C_SCL_H;
//	delay_us(40);	
//	I2C_SCL_L;
//	delay_us(20);
}

//不产生ACK应答		    
void IIC_NAck(void){
//	Set_SDA_Output();
//	I2C_SCL_L;
//	I2C_SDA_H;
//	delay_us(2);
//	I2C_SCL_H;
//	delay_us(2);
//	I2C_SCL_L;
}	

//IIC发送一个字节	  
void IIC_Send_Byte(unsigned char txd){                        
//	uint8_t t;  
//	Set_SDA_Output();	
//	I2C_SCL_L;
//	delay_us(10);
//	for(t = 0;t<8;t++)
//	{  		
//		if((txd&0x80)>>7)
//		{
//				I2C_SDA_H;
//		}
//		else
//		{
//				I2C_SDA_L;
//		}
//		txd<<=1;
//		delay_us(5);
//		I2C_SCL_H;
//		delay_us(15);
//		I2C_SCL_L;
//		delay_us(60);
//	}	 
} 	    
//读1个字节，ack=1时，发送ACK，ack=0，发送nACK   
uint8_t IIC_Read_Byte(uint8_t ack)
{
	uint8_t i,receive=0;
	
//	delay_us(2);    
//	Set_SDA_Input();
//	delay_us(2); 
//	for(i=0;i<8;i++ )
//	{
//		I2C_SCL_L;
//		delay_us(50);
//		I2C_SCL_H;
//		receive<<=1;
//		if(READ_I2CSDA())
//		{
//			receive++;   
//		}
//		delay_us(50);
//	}	
//	if (!ack)
//		IIC_NAck();
//	else
//		IIC_Ack();
	return receive;
}

 //CRC校验
uint8_t CRC8(uint8_t *ptr, uint8_t len,uint8_t key) 
{
	unsigned char i;
	unsigned char crc=0;
	while(len--!=0)
	{
		for(i=0x80; i!=0; i/=2)
		{
			if((crc & 0x80) != 0)
			{
				crc *= 2;
				crc ^= key;
			}
			else
				crc *= 2;

			if((*ptr & i)!=0)
				crc ^= key;
		}
		ptr++;
	}
	return(crc);
}


//写MT9818命令
void I2C_WriteBreq_MsgSBS(unsigned char SlaveAdd,unsigned char RegAdd,unsigned char date)  
{
	unsigned char crc=0;
	unsigned char buff[3];
	
  SlaveAdd = (SlaveAdd<<1);
	buff[0]=SlaveAdd;
	buff[1]=RegAdd;
	buff[2]=date;
	crc=CRC8(buff,3,7);
	IIC_Start(); 
	IIC_Send_Byte(SlaveAdd); 
	IIC_Wait_Ack();
	IIC_Send_Byte(RegAdd);
	IIC_Wait_Ack();
	IIC_Send_Byte(date);
	IIC_Wait_Ack();
	IIC_Send_Byte(crc);
	IIC_Wait_Ack();
	IIC_Stop();
	Delay_us(1000); 
}

//读MT9818命令
unsigned char I2C_GetRead_MsgSBS(unsigned char SlaveAdd,unsigned char RegAdd) {
	unsigned char rec_data = 0,rec_crc = 0;
	unsigned char buff[2];
	unsigned char crc_result = 0;
	static unsigned char error_count = 0;

	SlaveAdd = (SlaveAdd << 1);
	IIC_Start (); 
	IIC_Send_Byte(SlaveAdd); 
	IIC_Wait_Ack();
	IIC_Send_Byte(RegAdd);
	IIC_Wait_Ack();
	IIC_Stop();
	IIC_Start (); 
	SlaveAdd = SlaveAdd +1;	
	IIC_Send_Byte(SlaveAdd);  	//??è??óê??￡ê?
	IIC_Wait_Ack();
	Delay_us(100); 
	rec_data = IIC_Read_Byte(1);
	rec_crc = IIC_Read_Byte(0);
	IIC_Stop();
	Delay_us(1000); 
	buff[0] = SlaveAdd;
	buff[1] = rec_data;
	crc_result = CRC8(buff,2,7);	
	if (crc_result != rec_crc){		//crc 错误 表示通信异常
		error_count++;
		if (error_count >= 10){		//错误处理，比如初始化I2C
			error_count = 0;
		//初始化I2C硬件接口
		}
	}	
	return rec_data;
}

//=========================
//连续读MT9818
//==========================

void I2C_Read_Mult_BS(uint8_t SlaveAdd,uint8_t RegAdd,uint8_t *buf,uint8_t len) {
	uint8_t i,j;
	SlaveAdd = (SlaveAdd << 1);
	IIC_Start (); 
	IIC_Send_Byte(SlaveAdd); 
	IIC_Wait_Ack();
	IIC_Send_Byte(RegAdd);
	IIC_Wait_Ack();
	IIC_Stop();
	IIC_Start (); 
	SlaveAdd = SlaveAdd +1;	
	IIC_Send_Byte(SlaveAdd);  	//进入接收模式
	IIC_Wait_Ack();
	Delay_us(100); 
	for(i=0;i<len-1;i++){
		buf[i] = IIC_Read_Byte(1);
		for (j=0;j<50;j++);
	}
	buf[i] = IIC_Read_Byte(0);
	IIC_Stop();
	Delay_us(1000); 
}


float Get_BAT_ADC_GAIN(void){
	float data = 0;
	float value = 0;
	data = I2C_GetRead_MsgSBS(0x08,0x3f);
	value =  data / 4 + 368;
	return value;
}
float Get_BAT_ADC_GAIN1(void){
	float data = 0;
	float value = 0;
	data = I2C_GetRead_MsgSBS(0x08,0x40);
	value =  data / 4 + 368;
	return value;
}

float Get_BAT_ADC_GAIN2(void){
	float data = 0;
	float value = 0;
	data = I2C_GetRead_MsgSBS(0x08,0x41);
	value =  data / 4 + 368;
	return value;
}

float Get_BAT_ADC_GAIN3(void){
	float data = 0;
	float value = 0;
	data = I2C_GetRead_MsgSBS(0x08,0x42);
	value =  data / 4 + 368;
	return value; 
}

float Get_TS_ADC_GAIN(void){
	float data = 0;
	float value = 0;
	data = I2C_GetRead_MsgSBS(0x08,0x43);
	value =  data / 4+ 368;
	return value;
}

float Get_TS_ADC_OFFSET(void){
	float value = 0;
	value = I2C_GetRead_MsgSBS(0x08,0x43);
	return value;
}

float Get_CC_ADC_GAIN(void){
	float data = 0;
	float value = 0;
	data = I2C_GetRead_MsgSBS(0x08,0x3e);
	value =  data*0.04 + 8.52;
	return value;
}

void Get_All_Vol(void){
	uint8_t i = 0;
	float BAT_ADC_GAIN = 0;
	float BAT_ADC_GAIN1 = 0;
	float BAT_ADC_GAIN2 = 0;
	float BAT_ADC_GAIN3 = 0;
	volatile float vol[18] = {0};
	volatile uint16_t rd_vol[18] = {0};
	float TotalVol = 0;
	volatile uint8_t vol_index = 0;
	BAT_ADC_GAIN = Get_BAT_ADC_GAIN();
	BAT_ADC_GAIN1 = Get_BAT_ADC_GAIN1();
	BAT_ADC_GAIN2 = Get_BAT_ADC_GAIN2();
	BAT_ADC_GAIN3 = Get_BAT_ADC_GAIN3();    
	Delay_ms(1);
	//连续读 
	I2C_Read_Mult_BS(SLAVE_ADDRESS,VC1_ADDRESS,i2c_rev_data,72);
	for (i=0;i<72;i=i+4){
		rd_vol[vol_index] = (i2c_rev_data[i]<<8) | (i2c_rev_data[i+2]);
		if(vol_index<2){
			vol[vol_index] = rd_vol[vol_index] * BAT_ADC_GAIN / 1000;
		}else if(vol_index<4){
			vol[vol_index] = rd_vol[vol_index] * BAT_ADC_GAIN1 / 1000;
		}else if(vol_index<6){
			vol[vol_index] = rd_vol[vol_index] * BAT_ADC_GAIN2 / 1000;
		}else{
			vol[vol_index] = rd_vol[vol_index] * BAT_ADC_GAIN3 / 1000;	
		}
		printf("Bat[%d] is : %.2fmv\r\n",vol_index+1,vol[vol_index]);			
		Delay_ms(10);
		vol_index++;
	} 
	TotalVol =( I2C_GetRead_MsgSBS(0x08,0x30) << 8 | I2C_GetRead_MsgSBS(0x08,0x31) ) * BAT_ADC_GAIN3 * 8 / 1000;
	Delay_ms(10);
	printf("TotalVol is : %.2fmv\r\n",TotalVol);
	Delay_ms(10000);
}

void Get_All_Temp(void){
	uint8_t i = 0;
	float TS_ADC_OFFSET = 0;
	float TS_ADC_GAIN = 0;
	float Temp[4] = {0};
	TS_ADC_OFFSET = Get_TS_ADC_OFFSET();
	TS_ADC_GAIN = Get_BAT_ADC_GAIN();
	Delay_ms(1);
	for(i = 0;i<4;i++){
		if(TS_ADC_OFFSET>0x80){
			Temp[i] = (( (I2C_GetRead_MsgSBS(0x08,0x32+i*2) << 8 ) | (I2C_GetRead_MsgSBS(0x08,0x32+(i*2+1))) ) - (TS_ADC_OFFSET-0x80)) * TS_ADC_GAIN / 1000;
			Delay_ms(10);
			printf("Temp[%d] is : %.2f\r\n",i+1,Temp[i]);
			Delay_ms(10);
		}else{
			Temp[i] = (( (I2C_GetRead_MsgSBS(0x08,0x32+i*2) << 8 ) | (I2C_GetRead_MsgSBS(0x08,0x32+(i*2+1))) )+ TS_ADC_OFFSET ) * TS_ADC_GAIN / 1000;
			Delay_ms(10);
			printf("Temp[%d] is : %.2f\r\n",i+1,Temp[i]);
			Delay_ms(10000);			
		}
	}   
}

void Get_Current(void){
	float CC_ADC_GAIN = 0; 
	float CC = 0;
	CC_ADC_GAIN = Get_CC_ADC_GAIN() /1000;
	CC = (int16_t)((I2C_GetRead_MsgSBS(0x08,0x3c) << 8) | (I2C_GetRead_MsgSBS(0x08,0x3d))) * CC_ADC_GAIN;
	Delay_ms(10);
	printf("CC is : %.2fmv\r\n",CC);
	Delay_ms(10000);
}
